package com.xiaoyy.sso.gateway.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiaoyy.core.common.cache.CacheConst;
import com.xiaoyy.core.common.exception.AppException;
import com.xiaoyy.core.common.vo.AppResponse;
import com.xiaoyy.core.common.vo.BaseVO;
import com.xiaoyy.core.common.vo.SessionInfo;
import com.xiaoyy.core.common.vo.TokenVO;
import com.xiaoyy.core.config.util.RedisUtil;
import com.xiaoyy.core.config.util.TokenLoginHelper;
import com.xiaoyy.sso.common.enums.LoginTypeEnum;
import com.xiaoyy.sso.common.vo.LoginVO;
import com.xiaoyy.sso.common.vo.WinxinVO;
import com.xiaoyy.sso.core.integration.RsLoginIntegration;
import com.xiaoyy.sso.core.integration.SmsIntegration;
import com.xiaoyy.sso.core.util.WechatUtil;
import com.xiaoyy.sso.gateway.req.*;
import com.xiaoyy.sso.gateway.validators.LoginValidators;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * 就业创业码用户登入相关
 *
 * @author chenzh
 * @date 2018-08-17
 */
@RestController
@RequestMapping(value = "/sso/jycy")
@Api(tags = "账号管理")
public class IndexController {
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    RsLoginIntegration rsLoginIntegration;
    @Autowired
    TokenLoginHelper tokenLoginHelper;
    @Autowired
    SmsIntegration smsIntegration;
    /**
     * 用户登入
     */
    @PostMapping(value = "/login", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "用户登录", notes = "用户登录")
    public AppResponse<TokenVO> loginByUserName(@RequestBody @Validated(value = {LoginValidators.ToLogin.class}) LoginReq loginReq, @ApiIgnore HttpServletRequest request) {
        if (StringUtils.isBlank(loginReq.getLoginKey())) {
            if (request.getSession() != null) {
                //session 不为空为PC端
                loginReq.setLoginKey(request.getSession().getId());
            }
        }
        LoginVO loginVO = Convert.convert(LoginVO.class, loginReq);
        return AppResponse.successData(rsLoginIntegration.login(loginVO));
    }
    /**
     * 用户登入
     */
    @PostMapping(value = "/login/weixin", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "微信登录", notes = "用户登录")
    public AppResponse<TokenVO> loginWinxin(@RequestBody @Validated(value = {LoginValidators.ToLogin.class}) LoginWinxinReq loginReq, @ApiIgnore HttpServletRequest request) {
        if (StringUtils.isBlank(loginReq.getLoginKey())) {
            if (request.getSession() != null) {
                //session 不为空为PC端
                loginReq.setLoginKey(request.getSession().getId());
            }
        }
        LoginVO loginVO = Convert.convert(LoginVO.class, loginReq);
        if (StringUtils.isBlank(loginVO.getOpenId())) {
            loginVO.setOpenId(getWinxinOpenId(loginReq));
        }
        loginVO.setLoginType(LoginTypeEnum.weixin.getType());
        return AppResponse.successData(rsLoginIntegration.login(loginVO));
    }
    /**
     * 微信绑定用户
     */
    @PostMapping(value = "/bindUser/weixin", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "微信绑定用户", notes = "微信绑定用户")
    public AppResponse<TokenVO> bindWinxinUser(@RequestBody BindUserWinxinReq bindUserWinxinReq) {
        LoginVO loginVO = Convert.convert(LoginVO.class, bindUserWinxinReq);
        LoginWinxinReq loginWinxinReq= Convert.convert(LoginWinxinReq.class, bindUserWinxinReq);
        if (StringUtils.isBlank(loginWinxinReq.getOpenId())){
            loginVO.setOpenId(getWinxinOpenId(loginWinxinReq));
        }
        WinxinVO winxinVO= Convert.convert(WinxinVO.class, bindUserWinxinReq);
        return AppResponse.successData(rsLoginIntegration.bindWinxinUser(loginVO,winxinVO));
    }
    /**
     * 根据token获取用户信息
     * */
    @PostMapping(value = "/getSessionInfo", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "根据token获取用户信息", notes = "根据token获取用户信息")
    public AppResponse<SessionInfo> getSessionInfo(@RequestBody BaseVO baseVO) {
        return AppResponse.successData(tokenLoginHelper.getSessionInfo(baseVO.getAccessToken()));
    }
    /**
     * 获取验证码
     */
    @GetMapping(value = "/getImgCode")
    @ApiOperation(value = "获取图片验证码", notes = "获取图片验证码")
    public void getCode(@ApiParam("登录唯一key") @RequestParam(name="loginKey")String loginKey, @ApiIgnore HttpServletRequest request, @ApiIgnore HttpServletResponse response) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        String code = drawImg(output);
        if (StringUtils.isBlank(loginKey)) {
            if (request.getSession() != null) {
                //session 不为空为PC端
                loginKey = request.getSession().getId();
            }
        }
        redisUtil.set(CacheConst.LOGIN_IMG_CODE + loginKey, code,300);
        try {
            ServletOutputStream out = response.getOutputStream();
            output.writeTo(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 验证图片验证码
     */
    @GetMapping(value = "/check/imgCode")
    @ApiOperation(value = "校验图片验证码", notes = "校验图片验证码")
    public AppResponse checkImgCode(@ApiParam("登录唯一key") @RequestParam(name="loginKey")String loginKey,
                                    @ApiParam("图片验证码") @RequestParam(name="imgCode")String imgCode,
                                    @ApiIgnore HttpServletRequest request) {
        if (StringUtils.isBlank(loginKey)) {
            if (request.getSession() != null) {
                //session 不为空为PC端
                loginKey = request.getSession().getId();
            }
        }
        if (StringUtils.isBlank(loginKey)){
            return AppResponse.errorMsg("唯一标识不能为空");
        }
        if (redisUtil.hasKey(CacheConst.LOGIN_IMG_CODE + loginKey)){
            String code = redisUtil.get(CacheConst.LOGIN_IMG_CODE + loginKey).toString();
            if (code.equalsIgnoreCase(imgCode)){
                return AppResponse.successMsg("验证成功");
            }
        }else {
            return AppResponse.errorMsg("验证码已过期，请重新刷新");
        }
        return AppResponse.errorMsg("图形验证码输入不正确");
    }

    private String drawImg(ByteArrayOutputStream output) {

        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(70, 30, 4, 150);
        BufferedImage bi = lineCaptcha.getImage();
        String code = lineCaptcha.getCode();
        try {
            ImageIO.write(bi, "jpg", output);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return code;
    }

    /**
     * 用户注册
     */
    @PostMapping(value = "/register", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "用户注册", notes = "用户注册")
    public AppResponse<TokenVO> register(@RequestBody @Validated(value = {LoginValidators.Register.class}) RegisterReq registerReq) {
        LoginVO loginVO = Convert.convert(LoginVO.class, registerReq);
        return AppResponse.successData(rsLoginIntegration.register(loginVO));
    }

    /**
     * 退出登入
     */
    @PostMapping(value = "/logout", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "用户退出", notes = "用户退出")
    public AppResponse logout(@RequestBody BaseVO baseVO) {
        rsLoginIntegration.logout(baseVO.getAccessToken());
        return AppResponse.success();
    }
    /**
     * 获取微信openId
     * */
    private String getWinxinOpenId(LoginWinxinReq loginReq){
        String openId = loginReq.getOpenId();
        if (StringUtils.isBlank(openId)){
            openId = WechatUtil.getSessionKeyOrOpenId(loginReq.getCode()).getOpenId();
        }
        if (StringUtils.isBlank(openId)){
            throw new AppException("未获取到openid");
        }
        return openId;
    }

    /**
     * 登录、注册、找回密码发送短信 需要图片验证码
     */
    @RequestMapping(value = "/login/send/sms", produces = "application/json;charset=UTF-8")
    public AppResponse sendMsgLogin(@RequestBody LoginSmsReq smsReq, @ApiIgnore HttpServletRequest request) {
        if (StringUtils.isBlank(smsReq.getLoginKey())) {
            if (request.getSession() != null) {
                //session 不为空为PC端
                smsReq.setLoginKey(request.getSession().getId());
            }
        }
        if (StringUtils.isBlank(smsReq.getLoginKey())) {
            return AppResponse.errorMsg("登入唯一key不能为空");
        }
        if (StringUtils.isBlank(smsReq.getCellphone())) {
            return AppResponse.errorMsg("手机号码不能为空");
        }
        smsIntegration.loginSendMsg(smsReq.getCellphone(),smsReq.getSmsSendType(),smsReq.getUserType(),smsReq.getOrgId());
        return AppResponse.successMsg("发送成功");
    }

}
